#import "MRButton.h"
#import <AudioToolbox/AudioToolbox.h>

@implementation UIButton (Extension)

- (void)didLanguage
{
	[self setTitle:L(self.language) forState:UIControlStateNormal];
}

@end

/*===================================================================
 自定义按钮
 ==================================================================*/
@implementation MRButton

- (instancetype)initWithFrame:(CGRect)frame
{
	if (self = [super initWithFrame:frame])
	{
		[self setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter];
		[self setTitleColor:rgb(50, 50, 50) forState:UIControlStateNormal];
		
		self.contentMode = UIViewContentModeScaleAspectFit;
		
		[self awakeFromNib];
	}
	return self;
}

- (void)awakeFromNib
{
	[super awakeFromNib];
	//self.titleLabel.numberOfLines = 0;
	
	_longPress  = .4f;
	_fontNormal = self.titleLabel.font;
	_allowForce = _allowLongPress = _allowAnimation = YES;
}

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(NSUInteger)controlEvents
{
	[super addTarget:target action:action forControlEvents:controlEvents];
}

- (void)removeTarget:(id)target action:(SEL)action forControlEvents:(NSUInteger)controlEvents
{
	[super removeTarget:target action:action forControlEvents:controlEvents];
}

- (void)didLanguage
{
	self.title = L(self.language);
}

/*===================================================================
 说明:
	根据边界调区域
 ==================================================================*/
static CGRect edgeInsetsInsetRect(CGRect rect, UIEdgeInsets insets)
{
	if (insets.left && insets.left < 1.f)		insets.left   = rect.size.width * insets.left;
	if (insets.right && insets.right < 1.f)		insets.right  = rect.size.width * insets.right;
	if (insets.top && insets.top < 1.f)			insets.top    = rect.size.height * insets.top;
	if (insets.bottom && insets.bottom < 1.f)	insets.bottom = rect.size.height * insets.bottom;
	
	return UIEdgeInsetsInsetRect(rect, insets);
}

/*===================================================================
 说明:
	自定义布局
 ==================================================================*/
- (void)layoutSubviews
{
	[super layoutSubviews];
	
	UIControlState state = self.state;
	if (self.selected)
	{
		state = UIControlStateSelected;
		self.imageView.image = [self imageForState:state];
	}
	
	[self setShadowWithRadius:3 color:[self titleShadowColorForState:state] path:nil];
	
	self.titleLabel.textAlignment = self.contentHorizontalAlignment < 2 ? 1 - self.contentHorizontalAlignment : 2;
	self.imageView.clipsToBounds = NO;
	self.imageView.contentMode = self.contentMode;
	
	CGSize size  = self.bounds.size;
	CGRect rcImg = self.bounds;
	CGRect rcLab = self.bounds;
	
	//contentEdgeInsets 用于控制器文本与图像的位置，left,top,right,bottom 同时只能有一个生效
	//生效的值说明了图像所在位置, 若全为0则文本与图像都居中
	UIEdgeInsets c = self.contentEdgeInsets;
	if (c.left)				//图像在左边
	{
		rcImg.size.width = c.left >= 1.f ? c.left : size.width * c.left;
		rcLab = CGRectMake(rcImg.size.width, 0, size.width - rcImg.size.width, size.height);
	}
	else if (c.right)		//图像在右边
	{
		rcLab.size.width = c.right >= 1.f ? size.width - c.right : size.width * (1.f - c.right);
		rcImg = CGRectMake(rcLab.size.width, 0, size.width - rcLab.size.width, size.height);
	}
	else if (c.top)			//图像在上边
	{
		rcImg.size.height = c.top >= 1.f ? c.top : size.height * c.top;
		rcLab = CGRectMake(0, rcImg.size.height, size.width, size.height - rcImg.size.height);
	}
	else if (c.bottom)		//图像在下边
	{
		rcLab.size.height = c.bottom >= 1.f ? size.height - c.bottom : size.height * (1.f - c.bottom);
		rcImg = CGRectMake(0, rcLab.size.height, size.width, size.height - rcLab.size.height);
	}
	
	//图像与文本的框架
	self.imageView.frame  = edgeInsetsInsetRect(rcImg, self.imageEdgeInsets);
	self.titleLabel.frame = edgeInsetsInsetRect(rcLab, self.titleEdgeInsets);
}

#pragma mark - 动画
- (void)setHighlighted:(BOOL)highlighted
{
	if (self.highlighted != highlighted)
	{
		[super setHighlighted:highlighted];
		if (highlighted) [self startAnimation]; else [self stopAnimation];
	}
	self.titleLabel.font = [self titleFontForState:self.state];
}

- (void)setSelected:(BOOL)selected
{
	[super setSelected:selected];
	self.titleLabel.font = [self titleFontForState:self.state];
}

- (void)setEnabled:(BOOL)enabled
{
	[super setEnabled:enabled];
	self.titleLabel.font = [self titleFontForState:self.state];
}

/*===================================================================
 说明:
	特效动画展示
 ==================================================================*/
- (void)startAnimation
{
	if (!_allowAnimation) return;
	
	CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
	animation.duration = .3;
	animation.values = @[[NSValue valueWithCATransform3D:CATransform3DIdentity],
						 [NSValue valueWithCATransform3D:CATransform3DMakeScale(.8, .8, 1)],
						 [NSValue valueWithCATransform3D:CATransform3DMakeScale(.83, .83, 1)],
						 [NSValue valueWithCATransform3D:CATransform3DMakeScale(.8, .8, 1)]];
	
	if ([_delegate respondsToSelector:@selector(button:willAnimation:)])
		[_delegate button:self willAnimation:animation];
	
	if (animation.values.count)
	{
		self.layer.transform = [animation.values.lastObject CATransform3DValue];
		[self.layer addAnimation:animation forKey:@"transform"];
	}
}

- (void)stopAnimation
{
	if (!_allowAnimation) return;
	
	CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
	animation.delegate = self;
	animation.duration = .3;
	animation.values = @[[NSValue valueWithCATransform3D:self.layer.transform],
						 [NSValue valueWithCATransform3D:CATransform3DIdentity],
						 [NSValue valueWithCATransform3D:CATransform3DMakeScale(.97, .97, 1)],
						 [NSValue valueWithCATransform3D:CATransform3DIdentity]];
	
	if ([_delegate respondsToSelector:@selector(button:willAnimation:)])
		[_delegate button:self willAnimation:animation];
	
	if (animation.values.count)
	{
		self.layer.transform = [animation.values.lastObject CATransform3DValue];
		[self.layer addAnimation:animation forKey:@"transform"];
	}
}

- (void)animationDidStop:(CAKeyframeAnimation *)anim finished:(BOOL)flag
{
	if ([_delegate respondsToSelector:@selector(buttonDidStopAnimation:)])
		[_delegate buttonDidStopAnimation:self];
}

#pragma mark - 属性
/*===================================================================
 说明:
	属性设置
 ==================================================================*/
- (void)setImage:(UIImage *)image
{
	[self setImage:image forState:UIControlStateNormal];
}
- (UIImage *)image
{
	return [self imageForState:UIControlStateNormal];
}

- (void)setTitle:(NSString *)title
{
	[self setTitle:title forState:UIControlStateNormal];
}
- (NSString *)title
{
	return [self titleForState:UIControlStateNormal];
}

- (void)setFont:(UIFont *)font
{
	_fontNormal = font;
	self.titleLabel.font = [self titleFontForState:self.state];
}
- (UIFont *)font
{
	return _fontNormal;
}

- (void)setTitleFont:(UIFont *)font forState:(UIControlState)state
{
	if (state == UIControlStateNormal)
		_fontNormal = font;
	else if (state == UIControlStateHighlighted)
		_fontHighlighted = font;
	else if (state == UIControlStateSelected)
		_fontSelected = font;
	else if (state == UIControlStateDisabled)
		_fontDisabled = font;
	
	self.titleLabel.font = [self titleFontForState:self.state];
}

- (void)setHandler:(MRButtonEvent)handler
{
	_handler = handler;
}

- (UIFont *)titleFontForState:(UIControlState)state
{
	if (state == UIControlStateHighlighted && _fontHighlighted)
		return _fontHighlighted;
	else if (state == UIControlStateSelected && _fontSelected)
		return _fontSelected;
	else if (state == UIControlStateDisabled && _fontDisabled)
		return _fontDisabled;
	
	return _fontNormal;
}

- (void)didFinishOperated
{
	
}

#pragma mark - 触摸手势
- (void)actionForEvent:(NSNumber *)event
{
	_tmrValue = -1;
	[_tmrPress invalidate];
	
	if (event.intValue == UIControlEventTouchForce || event.intValue == UIControlEventTouchLongPress)
	{
		[self didFinishOperated];
	}
	
	self.userInteractionEnabled = NO;
	[self performSelector:@selector(performActione:) withObject:event afterDelay:.1];
}

- (void)performActione:(NSNumber *)event
{
	self.userInteractionEnabled = YES;
	[self sendActionsForControlEvents:(UIControlEvents)event.intValue];
}

//触摸计时
- (void)touchTimer
{
	_tmrValue += 0.02f;
	
	//如果有Force事件，但系统不支持则转为长按0.5秒
	if (_willForce && _tmrValue >= .5)
	{
		_willForce = NO;
		[self actionForEvent:@(UIControlEventTouchForce)];
	}
	//长按事件
	if (_willPress && _tmrValue >= _longPress)
	{
		_willPress = NO;
		[self actionForEvent:@(UIControlEventTouchLongPress)];
		if (_handler) _handler(self, UIControlEventTouchLongPress);
	}
}

//开始触摸
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	UITouch *touch = [touches allObjects].firstObject;
	
	_startPoint = [touch locationInView:self.superview];
	_tmrValue = 0;
	
	_tmrPress = [NSTimer timerWithTimeInterval:.02f target:self selector:@selector(touchTimer) userInfo:nil repeats:YES];
	[[NSRunLoop mainRunLoop] addTimer:_tmrPress forMode:NSRunLoopCommonModes];
	
	//检测是否支持Force
	_willForce = _allowForce && ((self.allControlEvents & UIControlEventTouchForce) != 0) && IOS9 && touch.maximumPossibleForce;
	_willPress = _allowLongPress && (self.allControlEvents & UIControlEventTouchLongPress) != 0;
	
	self.highlighted = YES;
}

//触摸移动检测，若小于指定范围示为合理抖动
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
	if (_tmrValue < 0) return;
	
	UITouch *touch = [touches allObjects].firstObject;
	CGPoint point  = [touch locationInView:self.superview];
	
	//触摸移动超出限制，取消本次事件检测
	if (!CGRectContainsPoint(self.frame, point) && (fabs(point.x - _startPoint.x) > 25 || fabs(point.y - _startPoint.y) > 25))
	{
		[self touchesCancelled:touches withEvent:event];
	}
	//3D Touch (Force)
	else if (_willForce && (touch.force == touch.maximumPossibleForce))
	{
		[self actionForEvent:@(UIControlEventTouchForce)];
		if (_handler) _handler(self, UIControlEventTouchForce);
	}
}

//完成触摸
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
	[_tmrPress invalidate];
	self.highlighted = NO;
	
	if (_tmrValue >= 0)
	{
		[self actionForEvent:@(UIControlEventTouchUpInside)];
		if (_handler) _handler(self, UIControlEventTouchClick);
	}
}

//取消触摸
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
	_tmrValue = -1;
	[_tmrPress invalidate];
	self.highlighted = NO;
}

@end
